/**
 * A gear joint is used to connect two joints together. Either joint
 * can be a revolute or prismatic joint. You specify a gear ratio
 * to bind the motions together:
 * coordinate1 + ratio * coordinate2 = constant
 * The ratio can be negative or positive. If one joint is a revolute joint
 * and the other joint is a prismatic joint, then the ratio will have units
 * of length or units of 1/length.
 * @warning You have to manually destroy the gear joint if joint1 or joint2
 * is destroyed.
**/
public class b2GearJoint extends b2Joint {

	//mock fields
	b2Joint m_joint1;
	b2Joint m_joint2;
	b2Vec2 m_localAnchorA;
	b2Vec2 m_localAnchorB;

	public b2GearJoint(int addr) {
		super(addr);

		m_joint1 = new b2Joint(jniJoint1(address));
		m_joint2 = new b2Joint(jniJoint2(address));
		m_localAnchorA = new b2Vec2(jniLocalAnchorA(addr));
		m_localAnchorB = new b2Vec2(jniLocalAnchorB(addr));
	}

	@Override
	public void release() {
		if ( address != 0 ) {
			m_joint1.address = 0;
			m_joint2.address = 0;
			m_localAnchorA.address = 0;
			m_localAnchorB.address = 0;
			super.release();
		}
	}

	public b2Vec2 GetAnchorA() {
		return m_bodyA.GetWorldPoint(m_localAnchorA);
	}

	public b2Vec2 GetAnchorB() {
		return m_bodyB.GetWorldPoint(m_localAnchorB);
	}

	public b2Vec2 GetReactionForce(float inv_dt) {
		return new b2Vec2(jniGetReactionForce(address, inv_dt));
	}

	public float GetReactionTorque(float inv_dt) {
		return jniGetReactionTorque(address, inv_dt);
	}

	/// Get the first joint.
	public b2Joint GetJoint1() {
		return m_joint1;
	}

	/// Get the second joint.
	public b2Joint GetJoint2() {
		return m_joint2;
	}

	/// Set the gear ratio.
	public void SetRatio(float ratio) {
		jniSetRatio(address, ratio);
	}

	/// Get the gear ratio.
	public float GetRatio() {
		return jniGetRatio(address);
	}

	private static native int jniJoint1(int me);
	private static native int jniJoint2(int me);
	private static native int jniLocalAnchorA(int me);
	private static native int jniLocalAnchorB(int me);

	private static native int jniGetReactionForce(int me, float inv_dt);
	private static native float jniGetReactionTorque(int me, float inv_dt);
	private static native void jniSetRatio(int me, float ratio);
	private static native float jniGetRatio(int me);
}
